package com.jzsm.modules.sender.senderService.impl.sms;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.jzsm.common.annotation.Channel;
import com.jzsm.common.exception.BusinessException;
import com.jzsm.common.utils.AssertUtils;
import com.jzsm.modules.sender.bo.accountConfig.SmsALiCloudAccountConfigBo;
import com.jzsm.modules.sender.bo.accountConfig.SmsHuaWeiCloudAccountConfigBo;
import com.jzsm.modules.sender.bo.accountConfig.SmsTencentCloudAccountConfigBo;
import com.jzsm.modules.sender.enums.ChannelTypeEnum;
import com.jzsm.modules.sender.pojo.PushChannelAccount;
import com.jzsm.modules.sender.senderService.AbstractMessageSender;
import com.jzsm.modules.sender.vo.SmsMessageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.Data;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 阿里云 短信渠道
 */
@Slf4j
@Component
@Channel(ChannelTypeEnum.SMSALiCloud)
public class SMSALiCloudMessageSender extends AbstractMessageSender {
    private static String ENDPOINT = "dysmsapi.aliyuncs.com";

    @Override
    public String sendMessage(String message, PushChannelAccount account) {
        return run(message, account);
    }

    public String run(String message, PushChannelAccount account) {
        TypeReference<SmsMessageVo<Map<String, Object>>> typeReference = new TypeReference<SmsMessageVo<Map<String, Object>>>() {
        };
        SmsMessageVo<Map<String, Object>> smsMessageVo = JSON.parseObject(message, typeReference);
        return run(smsMessageVo, account);
    }

    @SneakyThrows
    public Client createClient(SmsALiCloudAccountConfigBo configBo) {
        Config config = new Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId(configBo.getAccessKey())
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret(configBo.getAccessKeySecret());
        // 访问的域名
        config.endpoint = ENDPOINT;
        return new Client(config);
    }

    /**
     * 发送短信
     *
     * @return 返回结果
     */
    @SneakyThrows
    public String run(SmsMessageVo<Map<String, Object>> smsMessageVo, PushChannelAccount account) {
        String accountConfig = account.getAccountConfig();
        SmsALiCloudAccountConfigBo configBo = JSON.parseObject(accountConfig, SmsALiCloudAccountConfigBo.class);
        checkConfigBo(configBo);

        Client client = createClient(configBo);
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setSignName(configBo.getSignName())
                .setTemplateCode(configBo.getTemplateCode())
                .setPhoneNumbers(smsMessageVo.getPhoneNum());

        // 设置变量
        Map<String, Object> params = smsMessageVo.getParams();
        if (Objects.nonNull(params) && !params.isEmpty()) {
            sendSmsRequest.setTemplateParam(JSON.toJSONString(params));
        }

        RuntimeOptions runtime = new RuntimeOptions();
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime);

        SendSmsResponseBody body = response.getBody();
        AssertUtils.isTrue(body.getMessage(), "OK".equals(body.getCode()));

        return JSON.toJSONString(body);
    }

    private void checkConfigBo(SmsALiCloudAccountConfigBo configBo) {
        AssertUtils.isNotNull("accessKey 不允许为空！", configBo.getAccessKey());
        AssertUtils.isNotNull("accessKeySecret 不允许为空！", configBo.getAccessKeySecret());
        AssertUtils.isNotNull("signName 不允许为空！", configBo.getSignName());
        AssertUtils.isNotNull("templateCode 不允许为空！", configBo.getTemplateCode());
    }
}
